home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP06.ZIP / CHAP06 / POLYLINE / POLYWIN.CPP < prev    next >
C/C++ Source or Header  |  1993-03-27  |  7KB  |  269 lines

  1. /*
  2.  * POLYWIN.CPP
  3.  *
  4.  * Window procedure for the polyline drawing window and support functions.
  5.  * This window is not complicated.  On creation it allocates a block of
  6.  * memory for a POLYLINEDATA structure that contains 20 POINTs.  We do not
  7.  * attempt to reallocate this array at all just to maintain simplicity.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19.  
  20. #include <windows.h>
  21. #include <ole2.h>
  22. #include "polyline.h"
  23.  
  24.  
  25.  
  26. /*
  27.  * PolylineWndProc
  28.  *
  29.  * Purpose:
  30.  *  Window procedure for the polyline drawing window.
  31.  */
  32.  
  33. LRESULT __export FAR PASCAL PolylineWndProc(HWND hWnd, UINT iMsg
  34.     , WPARAM wParam, LPARAM lParam)
  35.     {
  36.     LPCPolyline     ppl;
  37.     PAINTSTRUCT     ps;
  38.     HDC             hDC;
  39.     POINT           pt;
  40.     RECT            rc;
  41.  
  42.     ppl=(LPCPolyline)GetWindowLong(hWnd, PLWL_STRUCTURE);
  43.  
  44.     switch (iMsg)
  45.         {
  46.         case WM_CREATE:
  47.             ppl=(LPCPolyline)((LPCREATESTRUCT)lParam)->lpCreateParams;
  48.             SetWindowLong(hWnd, PLWL_STRUCTURE, (LONG)ppl);
  49.  
  50.             //Since New repaints this window, we need to store the hWnd here.
  51.             ppl->m_hWnd=hWnd;
  52.             ppl->m_pIPolyline->New();
  53.             break;
  54.  
  55.  
  56.         case WM_PAINT:
  57.             hDC=BeginPaint(hWnd, &ps);
  58.             ppl->Draw(hDC, FALSE, TRUE);
  59.             EndPaint(hWnd, &ps);
  60.             break;
  61.  
  62.  
  63.         case WM_LBUTTONDOWN:
  64.             //Stop if we are already at the limit.
  65.             if (CPOLYLINEPOINTS==ppl->m_pl.cPoints)
  66.                 {
  67.                 MessageBeep(0);
  68.                 break;
  69.                 }
  70.  
  71.             //Convert the points into 0-32767 range
  72.             GetClientRect(hWnd, &rc);
  73.             pt=MAKEPOINT(lParam);
  74.             ppl->PointScale(&rc, &pt, FALSE);
  75.  
  76.             ppl->m_pl.rgpt[ppl->m_pl.cPoints++]=pt;
  77.  
  78.             //Draw the lines to this new point only.
  79.             hDC=GetDC(hWnd);
  80.             ppl->Draw(hDC, FALSE, FALSE);
  81.             ReleaseDC(hWnd, hDC);
  82.  
  83.             if (NULL!=ppl->m_pAdv)
  84.                 ppl->m_pAdv->OnPointChange();
  85.  
  86.             break;
  87.  
  88.  
  89.         default:
  90.             return DefWindowProc(hWnd, iMsg, wParam, lParam);
  91.         }
  92.  
  93.     return 0L;
  94.     }
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102. /*
  103.  * CPolyline::Draw
  104.  *
  105.  * Purpose:
  106.  *  Paints the current line in the polyline window.
  107.  *
  108.  * Parameters:
  109.  *  hDC             HDC to draw on, could be a metafile or printer DC.
  110.  *  fMetafile       BOOL indicating if hDC is a metafile or not, so we
  111.  *                  can avoid operations that RIP.
  112.  *  fEntire         BOOL indicating if we should draw the entire figure
  113.  *                  or not.
  114.  *
  115.  * Return Value:
  116.  *  None
  117.  */
  118.  
  119. void CPolyline::Draw(HDC hDC, BOOL fMetafile, BOOL fEntire)
  120.     {
  121.     HBRUSH          hBrush;
  122.     HPEN            hPen;
  123.     HGDIOBJ         hObj1, hObj2;
  124.     UINT            i, j;
  125.     UINT            uMM;
  126.     POINT           pt1, pt2;
  127.     RECT            rc;
  128.  
  129.     GetClientRect(m_hWnd, &rc);
  130.  
  131.     /*
  132.      * If the mapping mode is not MM_TEXT, convert the points to
  133.      * whatever mapping mode in in effect before drawing.
  134.      * This specifically supports metafiles in MM_ANISOTROPIC.
  135.      */
  136.     uMM=fMetafile ? MM_TEXT : GetMapMode(hDC);
  137.  
  138.     if (MM_TEXT!=uMM)
  139.         DPtoLP(hDC, m_pl.rgpt, m_pl.cPoints);
  140.  
  141.     hPen=CreatePen(m_pl.iLineStyle, 1, m_pl.rgbLine);
  142.     hObj1=SelectObject(hDC, hPen);
  143.  
  144.     hBrush=CreateSolidBrush(m_pl.rgbBackground);
  145.     hObj2=SelectObject(hDC, hBrush);
  146.     SetBkColor(hDC, m_pl.rgbBackground);
  147.  
  148.     /*
  149.      * Either draw the entire figure or just a single point.  The
  150.      * entire figure also includes erasing the background completely,
  151.      * since hDC may be a metafile DC.  Drawing a single point just
  152.      * updates the figure for that new point.
  153.      */
  154.     if (fEntire || 0==m_pl.cPoints)
  155.         {
  156.         //Erase the background for bitmaps and metafiles.
  157.         SelectObject(hDC, GetStockObject(NULL_PEN));
  158.         Rectangle(hDC, rc.left, rc.top, rc.right+1, rc.bottom+1);
  159.         SelectObject(hDC, hPen);
  160.  
  161.  
  162.         /*
  163.          * If we are drawing the entire figure, then loop through each
  164.          * point drawing a line to each successive point.
  165.          */
  166.  
  167.         for (i=0; i < m_pl.cPoints; i++)
  168.             {
  169.             for (j=i; j < m_pl.cPoints; j++)
  170.                 {
  171.                 pt1=m_pl.rgpt[i];
  172.                 pt2=m_pl.rgpt[j];
  173.                 PointScale(&rc, &pt1, TRUE);
  174.                 PointScale(&rc, &pt2, TRUE);
  175.                 MoveTo(hDC, pt1.x, pt1.y);
  176.                 LineTo(hDC, pt2.x, pt2.y);
  177.                 }
  178.             }
  179.         }
  180.     else
  181.         {
  182.         /*
  183.          * If we are only drawing the last point, just cycle once
  184.          * through previous points.
  185.          */
  186.  
  187.         //Get the last point entered in the array.
  188.         j=m_pl.cPoints-1;
  189.         pt1=m_pl.rgpt[j];
  190.         PointScale(&rc, &pt1, TRUE);
  191.  
  192.         for (i=0; i < j; i++)
  193.             {
  194.             pt2=m_pl.rgpt[i];
  195.             PointScale(&rc, &pt2, TRUE);
  196.  
  197.             MoveTo(hDC, pt1.x, pt1.y);
  198.             LineTo(hDC, pt2.x, pt2.y);
  199.             }
  200.         }
  201.  
  202.     //If we only had one point, draw a dot to indicate it's position.
  203.     if (1==m_pl.cPoints)
  204.         {
  205.         pt1=m_pl.rgpt[0];
  206.         PointScale(&rc, &pt1, TRUE);
  207.         SetPixel(hDC, pt1.x, pt1.y, m_pl.rgbLine);
  208.         }
  209.  
  210.     //Restore original points.
  211.     if (MM_TEXT!=uMM)
  212.         LPtoDP(hDC, m_pl.rgpt, m_pl.cPoints);
  213.  
  214.     SelectObject(hDC, hObj1);
  215.     SelectObject(hDC, hObj2);
  216.     DeleteObject(hBrush);
  217.     DeleteObject(hPen);
  218.     return;
  219.     }
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227. /*
  228.  * CPolyline::PointScale
  229.  *
  230.  * Purpose:
  231.  *  Scales a point to or from a relative window coordinate to a 0-32767
  232.  *  coordinate.
  233.  *
  234.  * Parameters:
  235.  *  pRect           LPRECT of the window.
  236.  *  ppt             LPPOINT to convert
  237.  *  fScaleToWindow  BOOL indicating direction of scaling.
  238.  *
  239.  * Return Value:
  240.  *  None
  241.  */
  242.  
  243. void CPolyline::PointScale(LPRECT pRect, LPPOINT ppt, BOOL fScaleToWindow)
  244.     {
  245.     DWORD   cx, cy;
  246.  
  247.     //Window size
  248.     cx=(DWORD)(pRect->right-pRect->left);
  249.     cy=(DWORD)(pRect->bottom-pRect->top);
  250.  
  251.     //Prevent crashes
  252.     if (0L==cx) cx=1;
  253.     if (0L==cy) cy=1;
  254.  
  255.     //Must use DWORD to insure proper scaling.
  256.     if (fScaleToWindow)
  257.         {
  258.         ppt->x=(UINT)(((DWORD)ppt->x*cx) >> 15);
  259.         ppt->y=(UINT)(((DWORD)ppt->y*cy) >> 15);
  260.         }
  261.     else
  262.         {
  263.         ppt->x=(UINT)(((DWORD)ppt->x << 15)/cx);
  264.         ppt->y=(UINT)(((DWORD)ppt->y << 15)/cy);
  265.         }
  266.  
  267.     return;
  268.     }
  269.